package com.hzw.saas.common.config.query;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;

import cn.hutool.core.collection.ListUtil;
import lombok.Data;

/**
 * 某属性相等和不等条件
 * eqs 和 nes 之间为 and 关系
 *
 * @author zzl
 * @since 07/01/2021
 */
@Data
public class LogicQuery<T> implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 条件相等，eqs元素之间为or关系
     */
    private final List<T> eqs = new ArrayList<>();

    /**
     * 条件不等，nes元素之间为and关系
     */
    private final List<T> nes = new ArrayList<>();


    public List<T> eqs() {
        return eqs;
    }

    public List<T> nes() {
        return nes;
    }

    public static <T> LogicQuery<T> none() {
        return new LogicQuery<T>();
    }

    @SafeVarargs
    public static <T> LogicQuery<T> eq(T... status) {
        LogicQuery<T> instance = new LogicQuery<>();
        List<T> list = ListUtil.toList(status);
        instance.eqs.addAll(list);
        return instance;
    }

    public static <T> LogicQuery<T> eq(Collection<T> status) {
        LogicQuery<T> instance = new LogicQuery<>();
        if (Objects.nonNull(status)) {
            instance.eqs.addAll(status);
        }
        return instance;
    }

    @SafeVarargs
    public static <T> LogicQuery<T> eq(boolean condition, T... status) {
        return condition ? LogicQuery.eq(status) : LogicQuery.none();
    }

    public static <T> LogicQuery<T> eq(boolean condition, Collection<T> status) {
        return condition ? LogicQuery.eq(status) : LogicQuery.none();
    }

    @SafeVarargs
    public static <T> LogicQuery<T> ne(T... status) {
        LogicQuery<T> instance = new LogicQuery<>();
        List<T> list = ListUtil.toList(status);
        instance.nes.addAll(list);
        return instance;
    }

    public static <T> LogicQuery<T> ne(List<T> status) {
        LogicQuery<T> instance = new LogicQuery<>();
        if (Objects.nonNull(status)) {
            instance.nes.addAll(status);
        }
        return instance;
    }

    @SafeVarargs
    public static <T> LogicQuery<T> ne(boolean condition, T... status) {
        return condition ? LogicQuery.ne(status) : LogicQuery.none();
    }

    public static <T> LogicQuery<T> ne(boolean condition, List<T> status) {
        return condition ? LogicQuery.ne(status) : LogicQuery.none();
    }

    public LogicQuery<T> orEq(T status) {
        this.eqs.add(status);
        return this;
    }

    public LogicQuery<T> orEq(boolean condition, T status) {
        return condition ? this.orEq(status) : this;
    }

    public LogicQuery<T> andNe(T status) {
        this.nes.add(status);
        return this;
    }

    public LogicQuery<T> andNe(boolean condition, T status) {
        return condition ? this.andNe(status) : this;
    }

    public boolean isEmpty() {
        return this.eqs.isEmpty() && this.nes.isEmpty();
    }

}
